package com.nvn.androidapp;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;

import android.app.AlertDialog;
import android.app.DatePickerDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.media.ExifInterface;
import android.net.Uri;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.provider.MediaStore;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.util.Log;
import android.view.View;
import android.view.WindowManager;
import android.widget.DatePicker;

import com.nostra13.universalimageloader.core.DisplayImageOptions;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;
import com.nvn.androidapp.Objects.CustomViewPager;
import com.nvn.androidapp.Objects.Document;
import com.nvn.androidapp.Objects.Picture;
import com.nvn.androidapp.adapters.DBAdapter;
import com.nvn.androidapp.adapters.FragmentAdapter;
import com.nvn.androidapp.fragments.InputInforFragment;
import com.nvn.androidapp.fragments.ViewImageFragment;
import com.nvn.androidapp.utils.Statics;
import com.viewpagerindicator.CirclePageIndicator;
import com.viewpagerindicator.PageIndicator;

public class ViewPagerActivity extends FragmentActivity implements OnPageChangeListener{
//	private View v;
	private ArrayList<Fragment> frags;
	private FragmentAdapter mAdapter;
	private CustomViewPager mPager;
	private PageIndicator mIndicator;
	private DBAdapter mDB;
	private Document doc;
	private ArrayList<Picture> pics;
	private Picture curPic;
	private ViewImageFragment curFrag;

    private ImageLoader imageLoader;
	private DisplayImageOptions options;
	private boolean ready = false, readyShuffle = true;
	private CountDownTimer cDT, cDTShuffle;
	private Uri fileUri;
	private int year, month, day, cur_page = 0;

	@Override
	protected void onCreate(Bundle arg0) {
		super.onCreate(arg0);
		setContentView(R.layout.layout_view_pager);
		
		init();
	}

	
	private void init() {
		getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
		
		Calendar c = Calendar.getInstance();
		year = c.get(Calendar.YEAR);
		month = c.get(Calendar.MONTH);
		day = c.get(Calendar.DAY_OF_MONTH);
		
		findViewById(R.id.imv_save).setVisibility(View.VISIBLE);
		findViewById(R.id.imv_camera).setVisibility(View.VISIBLE);
		doc = (Document) getIntent().getSerializableExtra("DOC");
		
		imageLoader = ImageLoader.getInstance();
		imageLoader.init(ImageLoaderConfiguration.createDefault(this));
		options = new DisplayImageOptions.Builder()
			.showStubImage(R.drawable.ic_no_image)
			.showImageForEmptyUri(R.drawable.ic_no_image)
			.showImageOnFail(R.drawable.ic_no_image)
			.cacheInMemory()
			.cacheOnDisc()
			.bitmapConfig(Bitmap.Config.RGB_565)
			.build();
		
		cDT = new CountDownTimer(3000, 3000) {
			
			@Override
			public void onTick(long arg0) {}
			
			@Override
			public void onFinish() {
				ready = false;
			}
		};
		
		cDTShuffle = new CountDownTimer(500, 500) {
			
			@Override
			public void onTick(long arg0) {}
			
			@Override
			public void onFinish() {
				readyShuffle = true;
			}
		};
		
		pics = new ArrayList<Picture>();
		mDB = new DBAdapter(this);
		
		if(-1 != doc.getID()){
			mDB.getPicturesByDoc(pics, doc.getID());
		}
		
		mPager = (CustomViewPager)findViewById(R.id.pager);
		mPager.setChildId(R.id.imv_viewimg);
		
		frags = new ArrayList<Fragment>();
		frags.add(InputInforFragment.newInstance(doc));
		
		for(Picture pic : pics){
			ViewImageFragment fr = ViewImageFragment.newInstance(pic, imageLoader, options);
			frags.add(fr);
		}
		
		mAdapter = new FragmentAdapter(this.getSupportFragmentManager(), frags);
		mPager.setAdapter(mAdapter);

        mIndicator = (CirclePageIndicator)findViewById(R.id.indicator);
        mIndicator.setViewPager(mPager);
        mIndicator.setOnPageChangeListener(this);
        mIndicator.setCurrentItem(0);
	}

	
	public void updateData(Picture pic){
		ViewImageFragment fr = ViewImageFragment.newInstance(pic, imageLoader, options);
		int index = cur_page+1;
		if(index>frags.size()|| index<0) index = frags.size();
		frags.add(index, fr);
		
		mAdapter = new FragmentAdapter(getSupportFragmentManager(), frags);
		mPager.setAdapter(mAdapter);
		mIndicator.setCurrentItem(index);
	}
	
	public byte[] getThumnail(){
		for(int i=1; i<frags.size(); i++){
			ViewImageFragment fr = (ViewImageFragment)frags.get(i);
			try{
				Bitmap bmp = fr.getThumnail(); 
				ByteArrayOutputStream stream = new ByteArrayOutputStream();
				bmp.compress(Bitmap.CompressFormat.PNG, 100, stream);
		        return stream.toByteArray();
			}catch(Exception e){
				return null;
			}
		}
		return null;
	}
	
	
	
	public void onSave(View v){
		byte[] thumb = getThumnail();
		if(frags.size()<2 || null == thumb){
			MainActivity.showToast(this, "Please take a picture first!");
			return;
		}
		
		InputInforFragment iif = (InputInforFragment)frags.get(0);
		Document doc = iif.saveData();
		doc.setThumb(thumb);
		int id_doc = -1;
		if(doc.getID() != -1){
			mDB.updateDocument(doc);
			id_doc = doc.getID();
		}else{
			id_doc = mDB.addDocument(doc);
		}
		for(int i=1; i<frags.size(); i++){
			ViewImageFragment vif = (ViewImageFragment)frags.get(i);
			Picture pic = vif.saveData();
			pic.setDocID(id_doc);
			pic.setIndex(i);
			if(pic.getID()>-1){
				mDB.updatePicture(pic);
			}else{
				mDB.addPicture(pic);
			}
		}
		MainActivity.showToast(this, "Successful!");
		finish();
	}

	public void onCamera(View v){
		startCameraIntent(Statics.CAMERA_REQUEST);
	}
	
	public void onShufflePicture(ViewImageFragment frag, Picture pic){
		if(!readyShuffle){
			MainActivity.showToast(this, "Don't touch so quickly!");
			return;
		}
		readyShuffle = false;
		cDTShuffle.start();
		
		int index = frags.indexOf(frag);
		if(index<frags.size()-1){
			ViewImageFragment tmp = (ViewImageFragment)frags.get(index+1);
			frag.saveData();
			tmp.saveData();
//			if(index==1){
//				frag.setGetThumb(false);
//				tmp.setGetThumb(true);
//			}
			
			frags.add(index, tmp);
			frags.remove(index+2);
			frags.trimToSize();
			mAdapter.notifyDataSetChanged();
			mPager.setAdapter(mAdapter);
			mIndicator.setCurrentItem(index);
		}
	}
	
	public void onDeletePicture(ViewImageFragment frag, Picture pic){
		int index = frags.indexOf(frag);
		int size = frags.size();
		
//		if(index==1 && index<size-1){
//			((ViewImageFragment)frags.get(index+1)).setGetThumb(true);
//		}
		if(pic.getID() != -1){
			mDB.delPicture(pic.getID());
		}
		File f = new File(pic.getPath());
		f.delete();
		
		frags.remove(frag);
		frags.trimToSize();
		mAdapter.notifyDataSetChanged();
		mPager.setAdapter(mAdapter);
		if(index<size-1) {
			mIndicator.setCurrentItem(index);
		}else{
			mIndicator.setCurrentItem(index-1);
		}
	}
	
	public void onReplacePicture(ViewImageFragment frag, Picture pic){
		curFrag = frag;
		curPic = pic;
		startCameraIntent(Statics.REPLACE_PIC_REQUEST);
	}
	
	private void startCameraIntent(int request){
		File folder = new File(Statics.MEDIA_STORAGE);
		folder.mkdirs();
	    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date());
	    fileUri = Uri.fromFile(new java.io.File(Statics.MEDIA_STORAGE + java.io.File.separator + "IMG_"
	        + timeStamp + ".jpg"));
	    
	    Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
//	    cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
		startActivityForResult(cameraIntent, request);
	}
	
	
	
	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		super.onActivityResult(requestCode, resultCode, data);
		
		/*String path =  "";
		if(null == data) {
			path = fileUri.getPath();
		}else{
			Bitmap mImageBitmap = (Bitmap) data.getExtras().get("data");
			path = saveBitmap2SDCard(mImageBitmap);
		}*/
		if(null == data) return;
		
		Bitmap mImageBitmap = (Bitmap) data.getExtras().get("data");
		String path = saveBitmap2SDCard(mImageBitmap);
		
		int degree = 0;
		
		try {
			ExifInterface exif = new ExifInterface(path);
			Log.d("EXIF value", exif.getAttribute(ExifInterface.TAG_ORIENTATION));
			if(exif.getAttribute(ExifInterface.TAG_ORIENTATION).equalsIgnoreCase("6")){
				degree = 90;
			}else if(exif.getAttribute(ExifInterface.TAG_ORIENTATION).equalsIgnoreCase("8")){
				degree = 270;
			}else if(exif.getAttribute(ExifInterface.TAG_ORIENTATION).equalsIgnoreCase("3")){
				degree = 180;
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		if(requestCode == Statics.CAMERA_REQUEST && resultCode == RESULT_OK){
			Picture pic = new Picture();
			pic.setID(-1);
			pic.setPath(path);
			pic.setDegree(degree);
			updateData(pic);
		}else if(requestCode == Statics.REPLACE_PIC_REQUEST && resultCode == RESULT_OK){
			curPic.setPath(path);
			curPic.setDegree(degree);
			mDB.updatePicture(curPic);
			curFrag.updateImage(path, degree);
			mAdapter.notifyDataSetChanged();
		}
	}
	
	private String saveBitmap2SDCard(Bitmap bmp){
		String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date());
	    File f = new java.io.File(Statics.MEDIA_STORAGE + java.io.File.separator + "IMG_"+ timeStamp + ".jpg");
		try {
		    FileOutputStream out = new FileOutputStream(f);
		    bmp.compress(Bitmap.CompressFormat.PNG, 100, out);
		    out.flush();
		    out.close();

		} catch (Exception e) {
		       e.printStackTrace();
		}
		return f.getPath();
	}
	
	@Override
	public void onBackPressed() {
		new AlertDialog.Builder(this)
		.setTitle("Notice")
		.setMessage("Are you sure you wish to discard the changes?")
		.setPositiveButton("Discard", new DialogInterface.OnClickListener() {
			
			@Override
			public void onClick(DialogInterface dialog, int which) {
				finish();
			}
		})
		.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
			
			@Override
			public void onClick(DialogInterface dialog, int which) {}
		})
		.show();
	}
	
	@Override
	protected void onDestroy() {
		imageLoader.clearDiscCache();
		imageLoader.clearMemoryCache();
		super.onDestroy();
	}
	
	public ArrayList<Fragment> getFrags(){
		return frags;
	}
	
	public void onSetDate(View v){
		new DatePickerDialog(this, datePickerListener,year, month,day).show();
	}
	
	
	private DatePickerDialog.OnDateSetListener datePickerListener  = new DatePickerDialog.OnDateSetListener() {
		
		// when dialog box is closed, below method will be called.
		public void onDateSet(DatePicker view, int selectedYear,
			int selectedMonth, int selectedDay) {
			year = selectedYear;
			month = selectedMonth;
			day = selectedDay;
			
			if(frags.size()>0 && frags.get(0) instanceof InputInforFragment){
				InputInforFragment fr = (InputInforFragment)frags.get(0);
				fr.setExpDate(new StringBuilder().append(month + 1)
						   .append("/").append(day).append("/").append(year)
						   .append(" ").toString().toString());
			}
		}
	};

	@Override
	public void onPageScrollStateChanged(int arg0) {}


	@Override
	public void onPageScrolled(int arg0, float arg1, int arg2) {}


	@Override
	public void onPageSelected(int arg0) {
		cur_page = arg0;
	}
}
